"""
    TagRate API handler
    
    @author: Jean-Lou Dupont
    
"""

import os
import sys
import logging
import string

from string import Template
from datetime import datetime

import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.api import users
from google.appengine.ext import db

from libs.user.prefs    import UserPrefs
from libs.tagrate.post  import TagRatePost
from libs.tagrate.atom  import AtomFeed

class TagRateFeedApiHandler(webapp.RequestHandler):
    
    API__    = '/api/tagrate/(.*?)/post/defaultv6'
    __LINK = 'http://www.web-bloks.com/api/tagrate/%s/post/defaultv6'
        
    def get(self, uid):
        """
            Retrieves the 'default' feed
            " /api/tagrate/(.*?)/post/defaultXX"
            i.e. the last 10 entries for the user 'uid' starting from 'date'
            The 'date' is conveyed through the ETag because it is less
            computational overhead than dealing with 'Last-Modified'.
        """
        up = UserPrefs.fromUid( uid )
        if not up:
            self.response.set_status( 400 ) #BAD UID
            self.response.out.write( "UNRECOGNIZED UID" )
            return

        user_agent = self.request.headers['User-Agent']
        
        #Revalidation call?
        # Support for ETag based validation only
        #==================
        try:    
                if_none_match     = self.request.headers['If-None-Match']
                #logging.info( 'TagRateFeedApiHandler.get, if-none-match[%s]' %       if_none_match )
        except: if_none_match     = None        

        user = up.user

        if ( if_none_match ):
            #remove the '"' guillement around the etag value
            fromDate = if_none_match.lstrip('"').rstrip('"')      
            self.handleRevalidation( user, if_none_match, fromDate, uid )
        else:
            self.handleFullFetch( user, None, uid )

    def handleRevalidation(self, user, etag, fromDate, uid ):
        
        (last_entry, reverse) = TagRatePost.datedList( user, fromDate, 1 )
        if last_entry:
            etag = '"' + str(last_entry[0].modified) + '"'
            if etag == fromDate:
                self.response.set_status( 304 ) #not-modified
                logging.info( 'TagRateFeedApiHandler: REVALIDATION, user[%s] etag[%s]' % (user, etag))                
                return
        
        return self.handleFullFetch( user, fromDate, uid )

    def handleFullFetch(self, user, fromDate, uid):
        
        feed = AtomFeed()
        link = self.__LINK % uid
        
        (liste, reverse) = TagRatePost.datedList( user, fromDate )
        
        try:
            (channel, last_modified) = feed.generateAtomFeed( user, link, liste, reverse )
            
            self.response.out.write( channel )
            self.response.set_status( 200 )
            self.response.headers['Content-Type']   = 'application/atom+xml'
            self.response.headers['Cache-Control']  = 'must-revalidate'
            
            if last_modified:
                etag = '"'+str( last_modified.modified )+'"'
                self.response.headers['ETag'] = etag
            else: 
                etag = ''
                     
        except Exception, e:
            logging.error('TagRateFeedApiHandler.handleFullFetch: EXCEPTION raised, msg[%s]' % e.message)
            self.response.set_status( 500 ) 
            return
        
        logging.info( 'TagRateFeedApiHandler: FULLFETCH, uid[%s] etag[%s]' % (uid, etag))

        
#========================================================================================================


__URLMAP = [    (TagRateFeedApiHandler.API__,     TagRateFeedApiHandler),
            ]

def main():
  application = webapp.WSGIApplication( __URLMAP, debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == "__main__":
    main()        